package be.novelfaces.test.common.festassert;

import org.fest.assertions.Assertions;
import org.fest.assertions.GenericAssert;
import org.jboss.test.faces.writer.ElementCriteria;
import org.jboss.test.faces.writer.NotFoundException;
import org.jboss.test.faces.writer.RecordingResponseWriter;

import be.novelfaces.component.util.element.ElementType;
import be.novelfaces.component.util.js.JS;

public class ResponseWriterAssert extends
		GenericAssert<ResponseWriterAssert, RecordingResponseWriter> {

	public ResponseWriterAssert(RecordingResponseWriter actual) {
		super(ResponseWriterAssert.class, actual);
	}

	public static ResponseWriterAssert assertThat(RecordingResponseWriter actual) {
		return new ResponseWriterAssert(actual);
	}

	public ResponseWriterAssert containsOnlyJS(String js) {
		isNotNull();
		ElementCriteria script = actual.find().element(JS.SCRIPT.getName())
				.withAttribute(JS.TYPE.getName(), JS.TEXT_JAVASCRIPT.getName()).atLevel(0)
				.atPosition(0);
		String errorJSMessage = "Expected " + JS.SCRIPT.getName()
				+ " element with attribute " + JS.TYPE.getName() + " equal to "
				+ JS.TEXT_JAVASCRIPT.getName() + ", but not found!";
		Assertions.assertThat(script.matches())
				.overridingErrorMessage(errorJSMessage).isTrue();
		String jsContent = null;
		try {
			jsContent = script.getText();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		String errorJSContentMessage = String.format(
				"Expected javascript to be <%s> but was <%s>", js, jsContent);
		Assertions.assertThat(jsContent)
				.overridingErrorMessage(errorJSContentMessage).isEqualTo(js);
		return this;
	}
	
	public ResponseWriterAssert containsElement(ElementType element) {
		isNotNull();
		Assertions.assertThat(element).overridingErrorMessage("Expecting Element not to be null").isNotNull();
		boolean matches = actual.find().element(element.getName()).matches();

		String errorMessage = String.format(
				"Expected element <%s> not found", element.getName());
		Assertions.assertThat(matches)
				.overridingErrorMessage(errorMessage).isTrue();
		return this;
	}

	public ResponseWriterAssert elementContainsAttributeValue(ElementType element,
			String attribute, Object attributeValue) {
		containsElement(element);
		try {
			Object value = actual.find().element(element.getName())
					.getAttribute(attribute);

			String errorMessage = String
					.format("Expected attributeValue <%s> not equal to actual attributeValue <%s>",
							attributeValue, value);
			Assertions.assertThat(value).overridingErrorMessage(errorMessage)
					.isEqualTo(attributeValue);
		} catch (NotFoundException e) {
			String errorMessage = String.format(
					"Attibute <%s> not found on element <%s>", attribute,
					element.getName());
			fail(errorMessage, e);
		}
		return this;
	}


}
